// 基于axios封装网络请求
// 每个程序员的想法都不一样, 封装的地方和名字都不一样, 但是思想相同
import theAxios from 'axios'
import { removeToken, getToken, setToken } from '@/utils/token.js'
import { Notify } from 'vant'
import { getNewTokenAPI } from '@/api'
// import { removeToken } from '@/utils/token.js'
const axios = theAxios.create({
  baseURL: 'http://geek.itheima.net', // 基地址
  timeout: 5000 // 5秒超时时间(请求5秒无响应直接判定超时)
})

// 请求拦截
axios.interceptors.request.use(config => {
// // 在发送请求之前做些什么
  // 目标: 统一携带token
  // 判断本地有token再携带, 判断具体api/index.js里如果没有携带Authorization, 我在添加上去
  // 未定义叫undefined, null具体的值你得赋予才叫空
  // ?. 可选链操作符, 如果前面对象里没有length, 整个表达式原地返回undefined
  // 如果getToken()在原地有值token字符串, 才能调用length获取长度
  if (getToken()?.length > 0 && config.headers.Authorization === undefined) { // 如果cookie中有用户的token 就把它添加到请求头中
    config.headers.Authorization = `Bearer ${getToken()}`
    // Cookies.get('Token')
  }
  return config
}, error => {
// Do something with request error
  return Promise.reject(error)
})

// 响应拦截
axios.interceptors.response.use(function (response) {
// Do something before response is sent
  return response
}, async function (error) {
  // 只有401才代表身份过期, 才需要跳转登录
  if (error.response.status === 401) {
    // error.response.status === 401 代表用户身份过期
    // 不能使用this.$router (因为this.$router是vue组件实例上的方法，这里无法调用$router)
    // 解决: 直接去上面引入@/router下router对象
    Notify({ type: 'warning', message: '身份已过期' })
    // 方式1: 强制跳转到登陆, 用户有感知
    removeToken() // 先清除token, 才能让路由守卫判断失效, 放行,去登录页
    // router.replace('/login')

    // 方式2: 刷新token(方式2清不清token都无所谓，反正你要重新在获取一次refresh_token了)
    // 使用refresh_token换回新的token再继续使用, JS代码实现, 用户无感知(效果好)
    const res = await getNewTokenAPI()
    console.log(res)
    // // 新的token回来之后, 我们要做什么
    // // 1. 更新token在本地
    setToken(res.data.data.token)
    // // 2. 更新新的token在请求头里
    error.config.headers.Authorization = `Bearer ${res.data.data.token}`
    // // 3. 未完成这次请求, 再一次发起
    // // error.config就是上一次请求的配置对象
    // // 结果我们要return回原本逻辑页面调用地方-还是return回去一个Promise对象
    return axios(error.config)// 通过 return axios(error.config)带着之前的配置对象再发一次之前没完成的请求
  }
  // Do something with response error
  return Promise.reject(error)
})

export default axios
